package Entity;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import static Util.Constants.*;

public final class Maze {
    public AStart astar;
    public int[] shortestPathDistances, pillIndices, powerPillIndices, junctionIndices;    //控制器信息
    public int initialPacManNodeIndex, lairNodeIndex, initialGhostNodeIndex;                //迷宫专用信息
    public Node[] graph;                                                                //实际的迷宫，存储为图形（节点集）
    public String name;                                                                    //迷宫的名称

    /*
     * 每个迷宫都存储为一个（连通）图：所有节点都有邻居，存储在长度为4的数组中。这个
     * 数组的索引与邻居所在的方向相关联：“[上，右，下，左]”。
     * 例如，如果节点“9”有相邻的“[-1,12，-1,6]”，则可以通过向右移动到达节点“12”，然后向左转。
     * 因此，控制器返回的方向应该是{0,1,2,3}，并且可以使用直接确定要转到的下一个节点。
     */
    public Maze(int index) {
        loadNodes(nodeNames[index]);
        loadDistances(distNames[index]);

        //create A* graph for shortest paths for the ghosts
        astar = new AStart();
        astar.createGraph(graph);
    }

    //从maze加载所有文件并初始化所有特定节点。
    private void loadNodes(String fileName) {
        try {
            @SuppressWarnings("resource")
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(pathMazes + System.getProperty("file.separator") + fileName + ".txt")));
            String input = br.readLine();

            //序言
            String[] pr = input.split("\t");

            this.name = pr[0];
            this.initialPacManNodeIndex = Integer.parseInt(pr[1]);
            this.lairNodeIndex = Integer.parseInt(pr[2]);
            this.initialGhostNodeIndex = Integer.parseInt(pr[3]);
            this.graph = new Node[Integer.parseInt(pr[4])];
            this.pillIndices = new int[Integer.parseInt(pr[5])];
            this.powerPillIndices = new int[Integer.parseInt(pr[6])];
            this.junctionIndices = new int[Integer.parseInt(pr[7])];

            int nodeIndex = 0;
            int pillIndex = 0;
            int powerPillIndex = 0;
            int junctionIndex = 0;

            input = br.readLine();

            while (input != null) {
                String[] nd = input.split("\t");

                Node node = new Node(Integer.parseInt(nd[0]), Integer.parseInt(nd[1]), Integer.parseInt(nd[2]), Integer.parseInt(nd[7]), Integer.parseInt(nd[8]),
                        new int[]{Integer.parseInt(nd[3]), Integer.parseInt(nd[4]), Integer.parseInt(nd[5]), Integer.parseInt(nd[6])});

                graph[nodeIndex++] = node;

                if (node.pillIndex >= 0)
                    pillIndices[pillIndex++] = node.nodeIndex;
                else if (node.powerPillIndex >= 0)
                    powerPillIndices[powerPillIndex++] = node.nodeIndex;

                if (node.numNeighbouringNodes > 2)
                    junctionIndices[junctionIndex++] = node.nodeIndex;

                input = br.readLine();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    /*
     * 加载已预先计算的最短路径距离。数据包含距迷宫中的任何节点到任何其他节点。
     * 由于图是对称的，对称性已经被移除以保持内存和所有距离存储在一个1D数组中；使用getDistance（-）查找它们。
     */
    private void loadDistances(String fileName) {
        this.shortestPathDistances = new int[((graph.length * (graph.length - 1)) / 2) + graph.length];

        try {
            @SuppressWarnings("resource")
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(pathDistances + System.getProperty("file.separator") + fileName)));
            String input = br.readLine();

            int index = 0;

            while (input != null) {
                shortestPathDistances[index++] = Integer.parseInt(input);
                input = br.readLine();
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

    }
}
